home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / DELPHI / FDRAG10.ZIP / FILEDRAG.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-04-10  |  5.1 KB  |  185 lines

  1. {*******************************************************************************
  2. *
  3. *  TFileDrag Component - Adds support for dropping files from explorer onto a 
  4. *                        a Delphi form.
  5. *
  6. *  Copyright (c) 1996 - Erik C. Nielsen ( 72233.1314@compuserve.com )
  7. *  All Rights Reserved
  8. *
  9. *******************************************************************************}
  10.  
  11. unit filedrag;
  12.  
  13. interface
  14.  
  15. uses
  16.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
  17.   ShellApi;
  18.  
  19. type
  20.   TFileDrag = class(TComponent)
  21.   private
  22.     FNameWithPath: TStrings;
  23.     FNameOnly: TStrings;
  24.     FExtension: TStrings;
  25.     FNumDropped: Integer;
  26.     FEnabled: Boolean;
  27.     FWndHandle: HWND;
  28.     FDefProc: Pointer;
  29.     FWndProcInstance: Pointer;
  30.     FOnDrop: TNotifyEvent;
  31.     
  32.     procedure DropFiles( hDropHandle: HDrop );
  33.     procedure SetEnabled( Value: Boolean );
  34.     procedure WndProc( var Msg: TMessage );
  35.     procedure InitControl;
  36.     procedure DestroyControl;
  37.   public
  38.     constructor Create(AOwner: TComponent); override;
  39.     destructor Destroy; override;
  40.   published
  41.     property NameWithPath: TStrings read FNameWithPath;
  42.     property NameOnly: TStrings read FNameOnly;
  43.     property Extension: TStrings read FExtension;
  44.     property FileCount: Integer read FNumDropped;
  45.     property EnableDrop: Boolean read FEnabled write SetEnabled default True;
  46.     property OnDrop: TNotifyEvent read FOnDrop write FOnDrop;
  47.   end;
  48.  
  49. procedure Register;
  50.  
  51. implementation
  52.  
  53. procedure Register;
  54. begin
  55.   RegisterComponents('System', [TFileDrag]);
  56. end;
  57.  
  58. constructor TFileDrag.Create( AOwner: TComponent );
  59. begin
  60.    inherited Create( AOwner );
  61.    FNumDropped := 0;
  62.    FNameWithPath := TStringList.Create;
  63.    FNameOnly := TStringList.Create;
  64.    FExtension := TStringList.Create;
  65.    FWndHandle := 0;
  66.  
  67.    InitControl;   
  68.    SetEnabled( FEnabled );
  69. end;
  70.  
  71. destructor TFileDrag.Destroy;
  72. begin
  73.   DestroyControl;
  74.   SetEnabled( FALSE );
  75.   inherited Destroy;
  76. end;
  77.  
  78. procedure TFileDrag.InitControl;
  79. var
  80.   WinCtl: TWinControl;
  81. begin
  82.    if Owner is TWinControl then
  83.     begin
  84.       { Subclass the owner so this control can capture the WM_DROPFILES message }
  85.       WinCtl := TWinControl( Owner );
  86.       FWndHandle := WinCtl.Handle;
  87.       FWndProcInstance := MakeObjectInstance( WndProc );
  88.       FDefProc := Pointer( GetWindowLong( FWndHandle, GWL_WNDPROC ));
  89.       SetWindowLong( FWndHandle, GWL_WNDPROC, Longint( FWndProcInstance ));
  90.     end
  91.    else
  92.     FEnabled := False; 
  93. end;
  94.  
  95. procedure TFileDrag.DestroyControl;
  96. begin
  97.   if FWndHandle <> 0 then
  98.    begin
  99.      { Restore the original window procedure }
  100.      SetWindowLong( FWndHandle, GWL_WNDPROC, Longint( FDefProc ));
  101.      FreeObjectInstance(FWndProcInstance);
  102.    end
  103. end;
  104.  
  105. procedure TFileDrag.SetEnabled( Value: Boolean );
  106. begin
  107.   FEnabled := Value;
  108.   { Call Win32 API to register the owner as being able to accept dropped files }
  109.   DragAcceptFiles( FWndHandle, FEnabled );
  110. end;
  111.  
  112. procedure TFileDrag.DropFiles( hDropHandle: HDrop );
  113. var
  114.   pszFileWithPath, pszFile, pszExt: PChar;
  115.   iFile, iPos, iStrLen, iTempLen: Integer;
  116. begin 
  117.   iStrLen := 128; 
  118.   pszFileWithPath := StrAlloc( iStrLen );
  119.   iFile := 0;
  120.  
  121.   { Clear any existing strings from the string lists }
  122.   FNameWithPath.Clear;
  123.   FNameOnly.Clear;
  124.   FExtension.Clear;
  125.   
  126.   { Retrieve the number of files being dropped }
  127.   FNumDropped := DragQueryFile( hDropHandle, $FFFFFFFF, pszFile, iStrLen );
  128.   
  129.   { Retrieve each file being dropped }
  130.   while ( iFile < FNumDropped ) do
  131.   begin
  132.    { Get the length of this file name }
  133.    iTempLen := DragQueryFile( hDropHandle, iFile, nil, 0 ) + 1;
  134.    { If file length > current PChar, delete and allocate one large enough }
  135.    if ( iTempLen > iStrLen ) then
  136.      begin
  137.        iStrLen := iTempLen;
  138.        StrDispose( pszFileWithPath );
  139.        pszFileWithPath := StrAlloc( iStrLen );
  140.      end;
  141.    { Get the fully qualified file name }
  142.    DragQueryFile( hDropHandle, iFile, pszFileWithPath, iStrLen );
  143.    { Get the extension and name parts }
  144.    iPos := StrLen( pszFileWithPath );
  145.    while ( iPos > 0 ) do
  146.     begin
  147.      Dec( iPos );
  148.      case pszFileWithPath[iPos] of
  149.        '.': pszExt := @pszFileWithPath[iPos+1];
  150.        '\': begin
  151.              pszFile := @pszFileWithPath[iPos+1];
  152.              iPos := 0;
  153.             end
  154.      end;
  155.     end;
  156.     { Add the file names to appropriate lists }
  157.     FNameWithPath.Add( StrPas( pszFileWithPath ));
  158.     FNameOnly.Add( StrPas( pszFile ));
  159.     FExtension.Add( StrPas( pszExt ));
  160.     Inc( iFile );
  161.   end;
  162.  
  163.   StrDispose( pszFileWithPath );
  164.  
  165.   { This will result in the OnDrop method being called, if it is defined }   
  166.   if Assigned(FOnDrop) then
  167.    begin
  168.     FOnDrop(Self);
  169.    end
  170. end;
  171.  
  172. procedure TFileDrag.WndProc( var Msg: TMessage );
  173. begin
  174.    with Msg do
  175.     begin
  176.        { If message is drop files, process, otherwise call the original window procedure }
  177.        if Msg = WM_DROPFILES then
  178.            DropFiles( HDrop( wParam ))
  179.        else
  180.            Result := CallWindowProc( FDefProc, FWndHandle, Msg, WParam, LParam);
  181.     end;        
  182. end;
  183.  
  184. end.
  185.